package peace.gui.controls.tooltip
{
	
import flash.display.DisplayObject;
import flash.display.InteractiveObject;
import flash.display.Stage;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Dictionary;
import flash.utils.Timer;

import peace.util.Logger;

/**
 * Карта и набор обработчиков для связывания InteractiveObject 
 * с любым объектом-тултипом (DisplayObject, появляющийся как тултип)
 * 
 */
public class Tooltips
{
	
	/**
	 * Скрываем ли тултип по клику 
	 */	
	public static var hideOnClick:Boolean = true;
	/**
	 * Карта объектов с тултипами <br>
	 * У объекта не может быть больше 1 тултипа 
	 */	
	private static var map:Dictionary = new Dictionary(false);
	/**
	 * хеш таймеров для появления с задержкой 
	 */
	private static var timers:Dictionary = new Dictionary(false);
	/**
	 * У любого объекта может быть только 1 тултип 
	 * 
	 * 
	 * @param target
	 * @param tooltip
	 * @param delay задержка появления в мс
	 * @param followCursor следовать ли за курсором в пределах объекта после появления
	 * 
	 */	
	public static function bind (target:InteractiveObject, tooltip:DisplayObject, delay:int = 500, followCursor:Boolean = false):void
	{
		if (map[target])
		{
			unbind(target);
		}
		map[target] = tooltip;
		
		if (delay > 0)
		{
			var timer:Timer = new Timer(delay);
			timer.addEventListener(TimerEvent.TIMER, onTimer, false,0,true);
			timers[target] = timer;
		}
		
		target.addEventListener(MouseEvent.ROLL_OVER, onRollOver, false,0,true);
		target.addEventListener(MouseEvent.ROLL_OUT, onRollOut, false,0,true);
		target.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown, false,0,true);
		
		if (followCursor)
		{
			target.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove, false,0,true);
		}
		
	}
	/**
	 * 
	 * @param target
	 * 
	 */	
	public static function unbind (target:InteractiveObject):void
	{
		if (map[target])
		{
			target.removeEventListener(MouseEvent.ROLL_OVER, onRollOver);
			target.removeEventListener(MouseEvent.ROLL_OUT, onRollOut);
			target.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			target.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
		}
		
		delete map[target];
		
		if (timers[target])
		{
			var timer:Timer = Timer (timers[target]);
			timer.stop();
			timer.removeEventListener(TimerEvent.TIMER, onTimer);
			delete timers[target];
		}
		
	}
	/**
	 * Позиционирование тултипа с учетом координат мышки 
	 * 
	 * @param tooltip
	 * 
	 */	
	private static function placeTooltip (tooltip:DisplayObject):void
	{
		var stage:Stage = tooltip.stage;
		
		if (!stage) return;
		
		var shift:Point = new Point(0, 20)
		var r:Rectangle = new Rectangle(stage.mouseX, stage.mouseY, tooltip.width, tooltip.height);
		
		tooltip.x = Math.min (stage.stageWidth-r.width, r.x + shift.x);
		
		if (r.bottom + shift.y > stage.stageHeight) // сверху
		{
			tooltip.y = r.y - r.height - shift.y/2;
		}
		else
		{
			tooltip.y = r.y + shift.y;
		}
	}
	/**
	 * 
	 * @param e
	 * 
	 */	
	private static function onRollOver (e:MouseEvent):void
	{
		var target:InteractiveObject = InteractiveObject(e.currentTarget);
		var tooltip:DisplayObject = DisplayObject(map[target]);
		var timer:Timer = Timer (timers[target]);
		
		if (timer)
		{
			timer.start();
		}
		else
		{
			target.stage.addChild(tooltip);
			placeTooltip(tooltip);
		}
		
	}
	/**
	 * 
	 * @param e
	 * 
	 */	
	private static function onRollOut (e:MouseEvent):void
	{
		var target:InteractiveObject = InteractiveObject(e.currentTarget);
		var tooltip:DisplayObject = DisplayObject(map[target]);
		var timer:Timer = Timer (timers[target]);

		var stage:Stage = target.stage || tooltip.stage;
		if (stage && stage.contains(tooltip))
		{
			stage.removeChild(tooltip);
		}
		
		if (timer) timer.stop();
	}
	/**
	 * 
	 * @param e
	 * 
	 */	
	private static function onMouseMove (e:MouseEvent):void
	{
		var target:InteractiveObject = InteractiveObject(e.currentTarget);
		var tooltip:DisplayObject = DisplayObject(map[target]);
		
		placeTooltip(tooltip);
		
		e.updateAfterEvent();
		
	}
	/**
	 * 
	 * @param e
	 * 
	 */	
	private static function onMouseDown (e:MouseEvent):void
	{
		if (hideOnClick)
		{
			onRollOut(e);
		}
	}
	/**
	 * 
	 * @param e
	 * 
	 */	
	private static function onTimer (e:TimerEvent):void
	{
		var timer:Timer = Timer(e.target);
		var tooltip:DisplayObject;
		
		// ищем свой тултип
		var target:*, t:Timer;
		for (target in timers)
		{
			t = Timer(timers[target]);
			if (t == timer)
			{
				tooltip = DisplayObject(map[target]);
				target.stage.addChild(tooltip);
				placeTooltip(tooltip);
				
				timer.stop();
				break;
			}
		}
		
		// если свой тултип не нашли
		if (!tooltip)
		{
			Logger.error("Не нашли тултип то!!!")
		}
		
	}
	
	
}
}